<!-- 用户管理 -->
<template>
  <div class="user-manage">
    <!-- 新增、搜索 -->
    <div class="search">
      <el-button type="primary" @click="onShowUserDialog(null, 'CREATE')" class="add-user-btn">新增用户</el-button>
      <search placeholder="请输入用户名称" :live-search="true" :search-word.sync="userName" @search="onSearch"/>
    </div>
    <!-- 用户列表 -->
    <div class="users-table">
      <el-table :data="tableData" stripe v-loading="loading" style="width: 100%">
        <el-table-column prop="userName" label="用户名" min-width="180px"></el-table-column>
        <el-table-column label="用户状态" min-width="250px">
          <template slot-scope="scope">
            <span>{{ getUserStatus(scope) }}</span>
            <el-divider direction="vertical"></el-divider>
            <el-button type="primary" size="small" @click="onClickUserStatus(scope)" class="lock-btn" plain>{{ scope.row.isLock == '0' ? '锁定': '解锁' }}</el-button>
          </template>
        </el-table-column>
        <el-table-column prop="description" label="用户描述" min-width="300px"></el-table-column>
        <el-table-column label="操作" min-width="400px">
          <template slot-scope="scope">
              <el-tooltip content="用户详情" placement="top">
                  <el-button type="text" @click="onShowDetail(scope)" class="btn-icon-box">
                      <i class="el-icon-view opt-icon"></i>
                  </el-button>
              </el-tooltip>
              <el-divider direction="vertical"></el-divider>
              <el-tooltip content="编辑用户" placement="top">
                  <el-button type="text" @click="onShowUserDialog(scope, 'UPDATE')" class="btn-icon-box">
                      <i class="el-icon-edit opt-icon"></i>
                  </el-button>
              </el-tooltip>
              <el-divider direction="vertical"></el-divider>
              <el-tooltip content="修改密码" placement="top">
                  <el-button type="text" @click="onShowUserDialog(scope, 'EDIT_PWD')" class="btn-icon-box">
                      <i class="el-icon-key opt-icon"></i>
                  </el-button>
              </el-tooltip>
              <el-divider direction="vertical"></el-divider>
              <el-tooltip content="下载 keytab" placement="top">
                  <el-button type="text" @click="onDownloadKeytab(scope)" class="btn-icon-box">
                      <i class="el-icon-download opt-icon"></i>
                  </el-button>
              </el-tooltip>
              <el-divider direction="vertical"></el-divider>
              <el-tooltip content="删除用户" placement="top">
                  <el-button type="text" @click="onShowDeleteDialog(scope)" class="btn-icon-box">
                      <i class="el-icon-delete opt-icon"></i>
                  </el-button>
              </el-tooltip>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <!-- 分页(默认 10条/页) -->
    <pagination 
        :total="userNum"
        :current-page="currentPage"
        :page-size="pageSize"
        @currentPageChange="handleCurrentChange"
        @pageSizeChange="handlePageSizeChange"
    />
    <!-- 用户表单（对话框） -->
    <el-dialog
      title="用户信息"
      :visible.sync="showUserDialog" 
      width="40%">
      <span slot="title">{{ userDialogTitle }}</span>
      <el-form :model="userForm" :rules="userFormRules" ref="userForm" label-width="120px">
        <el-form-item label="用户名称" prop="userName" v-if="showCondition.userName">
          <el-input 
            v-model="userForm.userName" 
            :disabled="userNameDisabled" 
            autocomplete="off" 
            placeholder="请输入用户名称"
          />
        </el-form-item>
        <el-form-item label="用户密码" prop="userPwd" v-if="showCondition.password">
          <el-input v-model="userForm.userPwd" autocomplete="off" placeholder="请输入用户密码" show-password></el-input>
        </el-form-item>
        <el-form-item label="确认用户密码" prop="userVerifyPwd" v-if="showCondition.verifyPwd">
          <el-input v-model="userForm.userVerifyPwd" autocomplete="off" placeholder="请再次输入用户密码" show-password></el-input>
        </el-form-item>
        <el-form-item label="用户描述" prop="description" v-if="showCondition.description">
          <el-input v-model="userForm.description" type="textarea" :autosize="{ minRows: 1, maxRows: 3}" placeholder="请输入用户描述信息"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="onCloseUserDialog">取 消</el-button>
        <el-button type="primary" @click="onSubmitUserForm" :loading="isCheckingUserName || formLoading">{{ submitBtnTxt }}</el-button>
      </span>
    </el-dialog>
    <!-- 用户详情（对话框） -->
    <person-detail 
      titleTxt="用户详情"
      v-if="showDetail" 
      :visible.sync="showDetail" 
      :person="detailObj" 
      @cleanData="cleanDetailObj"
    />
    <!-- 删除用户（对话框） -->
    <el-dialog
      title="确认删除"
      :visible.sync="showDeleteDialog"
      width="30%">
      <span slot="title">是否确认删除用户 {{userForm.userName}} ？</span>
      <span slot="footer" class="dialog-footer">
        <el-button @click="onCloseDeleteDialog">取 消</el-button>
        <el-button type="primary" @click="onDeleteUser" :loading="delLoading">{{ delLoading ? '提交中 ...' : '确 定' }}</el-button>
      </span>
    </el-dialog>
    <!-- 确认弹框 -->
    <confirm 
      :title="confirmTitle" 
      :showConfirm="showConfirm" 
      @closeConfirm="closeConfirm" 
      @submitConfirm="submitLockOrUnlock"
    />
  </div>
</template>
<script>
import _ from 'lodash';
import { mapState } from 'vuex';
import { Message } from 'element-ui';
import { tenantApi } from '@/request';
import { downloadKeytab, validatePwdForElementUI, validateVerifyPwdForElementUI, validateUserNameForElementUI, validateSearchName, resetForm } from '@/utils';
import { USER_LOCK_MAP, DEFAULT_PAGE_SIZE } from '@/const';
import personDetail from "@/components/manager/PersonDetail";
import confirm from '@/components/manager/Confirm';
import Pagination from '@/components/common/Pagination.vue';
import Search from '@/components/common/Search';

export default {
  components: { confirm, personDetail, Search, Pagination },
  data() {
    const validateName = (rule, value, callback) => {
        validateUserNameForElementUI(value, { auth: '用户', status: this.userDialogStatus }, callback, this.setCheckingUserNameCallback);
    };
    const validateVerifyPwd = (rule, value, callback) => {
        validateVerifyPwdForElementUI(value, this.userForm.userPwd, callback);
    };
    return {
      userName: '', // 查询字段
      tableData: [], // 用户列表
      loading: false,
      userNum: 0, // 列表项总条数
      currentPage: 1, // 当前页数
      pageSize: DEFAULT_PAGE_SIZE, // 每页列表项数
      showDetail: false,
      detailObj: { id: '', type: '', name: '', description: '', isLock: ''}, // 详情内容
      showDeleteDialog: false,
      userDialogStatus: null, // 'CREATE'/'UPDATE'/'EDIT_PWD'/null
      confirmTitle: '',
      showConfirm: false,
      formLoading: false,
      delLoading: false,
      userForm: { // 用户表单详情
        userId: '',
        userName: '',
        userPwd: '',
        userVerifyPwd: '',
        description: '',
        isLock: ''
      },
      userFormRules: {
        userName: [{ required: true, validator: validateName, trigger: 'blur' }],
        userPwd: [{ required: true, validator: validatePwdForElementUI, trigger: 'blur' }],
        userVerifyPwd: [{ required: true, validator: validateVerifyPwd, trigger: 'blur' }],
        description: [{ max: 200, message: '请输入200以内的字符', trigger: 'blur' }]
      },
      isCheckingUserName: false
    };
  },
  computed: {
      hasData() {
        return this.userNum > 0;
      },
      showUserDialog: {
        get() {
          return !!this.userDialogStatus;
        },
        set(val) {
          this.userDialogStatus = null;
          this.cleanUserForm();
        }
      },
      userDialogTitle() {
        let dialogTitleMap = {
          'CREATE': '新建用户信息',
          'UPDATE': '编辑用户信息',
          'EDIT_PWD': '修改密码'
        };
        return _.get(dialogTitleMap, this.userDialogStatus, '用户信息');
      },
      showCondition() {
        if (!this.userDialogStatus) return false;
        let status = this.userDialogStatus;
        let showMap = {
          'userName': status == 'CREATE' || status == 'UPDATE',
          'password': status == 'CREATE' || status == 'EDIT_PWD',
          'verifyPwd': status == 'CREATE' || status == 'EDIT_PWD',
          'description': status == 'CREATE' || status == 'UPDATE',
        };
        return showMap;
      },
      userNameDisabled() {
        return !!this.userForm.userId;
      },
      submitBtnTxt() {
        // 网速慢时，‘用户名去重校验’与‘提交表单’ 请求会pending，避免重复提交表单
        if (this.isCheckingUserName) {
          return '用户名校验中 ...';
        } else if (this.formLoading) {
          return '提交中 ...'
        } else {
          return '确 定'
        }
      }
  },
  mounted() {
    // 拉取列表信息
    this.getUserList({pageIndex: this.currentPage, pageSize: 10, isTenantGetTen: '0' });
  },
  methods: {
    setCheckingUserNameCallback(flag) {
      this.isCheckingUserName = flag;
    },
    getUserList(param = {pageIndex: 1, pageSize: 10, isTenantGetTen: '0'}) { // 拉取用户列表
      this.loading = true;
      tenantApi.getUserList(param).then((res) => {
        this.loading = false;
        this.userNum = _.get(res, 'count', 0);
        this.tableData = _.get(res, 'pageList', []);
        this.currentPage = param.pageIndex; // 同步列表分页
      }).catch(err => {
        this.loading = false;
      })
    },
    setUserForm(scope) {
      // 根据当前用户id，从列表中获取 user信息，传给 dialog
      let userId = scope.row['userId']; // 列表中当前行的 userId
      let currentUser = (this.tableData.filter((item, idx) => {
        return item.userId == userId;
      }) || [])[0];
      if (currentUser) {
        this.userForm.userName = currentUser.userName;
        this.userForm.userId = currentUser.userId;
        this.userForm.description = currentUser.description;
        this.userForm.isLock = currentUser.isLock;
      }
      // 错误用法：this.userForm = currentUser; 
      // 对象为引用类型，会导致 userForm 与 tableData 的当前项 指向同一地址
    },
    cleanUserForm() {
      // 每次关闭 userDialog，需要初始化 userForm
      this.userForm = {userName: '', userId: '', description: '', userPwd: '', userVerifyPwd: '', isLock: ''};
    },
    getUserStatus(scope) { // 列表展示“用户状态”转换
      let isLock = scope.row['isLock'];
      return USER_LOCK_MAP[isLock];
    },
    onClickUserStatus(scope) {
      this.showConfirm = true;
      this.setUserForm(scope);
      let txt = {
        status: scope.row.isLock == '0' ? '锁定' : '解锁',
        name: scope.row.userName
      };
      this.confirmTitle = `您是否确认${txt.status}用户 ${txt.name} ？`;
    },
    closeConfirm() {
      this.showConfirm = false;
      this.confirmTitle = '';
      this.cleanUserForm();
    },
    submitLockOrUnlock() { // 解锁用户
      let form = this.userForm 
      const user = {
        type: form.isLock,
        userId: form.userId
      };
      let text = form.isLock == '0' ? '已锁定' : '已解锁';
      tenantApi.unlockUser(user).then(res => {
        this.closeConfirm();
        Message.success(`用户 ${form.userName} ${text}`);
        this.getUserList({pageIndex: 1, pageSize: 10, userName: this.userName, isTenantGetTen: '0' });
      }).catch(err => {
        this.closeConfirm();
      })
    },
    onShowDetail(scope) { // 详情页
      this.showDetail = true;
      // 设置用户信息
      this.detailObj.type = 'USER';
      this.detailObj.id = scope.row.userId;
      this.detailObj.name = scope.row.userName;
      this.detailObj.isLock = scope.row.isLock;
      this.detailObj.description = scope.row.description;
    },
    cleanDetailObj() {
      this.detailObj = { id: '', type: '', name: '', description: '', isLock: ''};
    },
    onShowUserDialog(scope, status) { // 打开用户dialog
      switch(status) {
        case 'CREATE':
          this.userDialogStatus = 'CREATE';
          break;
        case 'UPDATE':
          this.setUserForm(scope);
          this.userDialogStatus = 'UPDATE';
          break;
        case 'EDIT_PWD':
          this.setUserForm(scope);
          this.userDialogStatus = 'EDIT_PWD';
          break;
        default:
          return;
      }
    },
    onCloseUserDialog() { // 关闭用户dialog
      if (this.userDialogStatus == 'UPDATE' || 
      this.userDialogStatus == 'EDIT_PWD') {
        this.cleanUserForm();
      }
      this.userDialogStatus = null;
      resetForm(this.$refs['userForm']);
    },
    onSubmitUserForm() { // 提交用户dialog
      this.$refs['userForm'].validate((valid) => {
        if (valid) { // 校验通过，提交数据
          this.formLoading = true;
          switch(this.userDialogStatus) {
            case 'CREATE':
              this.onCreateUser();
              break;
            case 'UPDATE':
              this.onUpdateUser();
              break;
            case 'EDIT_PWD':
              this.onUpdatePwd();
              break;
            default:
              return;
          }
        } else {
          return false;
        }
      });
    },
    onCreateUser() { // 新建用户提交
      let user = {
        userName: this.userForm.userName,
        password: this.userForm.userPwd,
        description: this.userForm.description
      };
      tenantApi.addUser(user).then((res) => {
        this.formLoading = false;
        this.onCloseUserDialog();
        Message.success("新用户创建成功");
        this.getUserList({pageIndex: 1, pageSize: 10, isTenantGetTen: '0'});
      }).catch(err => {
        this.formLoading = false;
      })
    },
    onUpdateUser() { // 编辑用户提交
      let user = {
        userId: this.userForm.userId,
        description: this.userForm.description
      };
      tenantApi.updateUser(user).then((res) => {
        this.formLoading = false;
        this.onCloseUserDialog();
        Message.success("编辑用户成功");
        this.getUserList({pageIndex: 1, pageSize: 10, userName: this.userName, isTenantGetTen: '0'});
      }).catch(err => {
        this.formLoading = false;
      })
    },
    onUpdatePwd() {
      let user = {
        userId: this.userForm.userId,
        newPassword: this.userForm.userPwd
      };
      tenantApi.changeUserPwd(user).then((res) => {
        this.formLoading = false;
        this.onCloseUserDialog();
        Message.success("修改密码成功");
        this.getUserList({pageIndex: 1, pageSize: 10, userName: this.userName, isTenantGetTen: '0'});
      }).catch(err => {
        this.formLoading = false;
      })
    },
    onDownloadKeytab(scope) { // 下载keytab
      downloadKeytab(scope.row.userId);
    },
    onShowDeleteDialog(scope) { // 删除用户
      this.setUserForm(scope);
      this.showDeleteDialog = true;
    },
    onCloseDeleteDialog() {
      this.cleanUserForm();
      this.showDeleteDialog = false;
    },
    onDeleteUser() { // 确认删除用户，提交后台
      let user = { userId: this.userForm.userId };
      this.delLoading = true;
      tenantApi.deleteUser(user).then((res) => {
        this.delLoading = false;
        this.onCloseDeleteDialog();
        Message.success("用户删除成功");
        this.getUserList({pageIndex: this.currentPage, pageSize: 10, userName: this.userName, isTenantGetTen: '0'});
      }).catch(err => {
        this.delLoading = false;
        Message.error(err.msg);
      })
    },
    onSearch() { // 列表查询
      // validateSearchName(this.userName) && 
      this.getUserList({pageIndex: 1, pageSize: this.pageSize, userName: this.userName, isTenantGetTen: '0'});
    },
    handleCurrentChange(val) { // 分页
      this.currentPage = val;
      this.getUserList({pageIndex: val, pageSize: this.pageSize, userName: this.userName, isTenantGetTen: '0'});
    },
    // pageSize变化的回调
    handlePageSizeChange(pageSize) {
        let param = { 
            pageIndex: 1, 
            pageSize, 
            isTenantGetTen: '0'
        }
        if (this.userName) {
            param.userName = this.userName
        }
        this.pageSize = pageSize;
        this.getUserList(param)
    },
  }
};
</script>
<style scoped lang="scss">
@import '~@/styles/userListCommon.scss';
</style>
